import { Component, OnInit } from '@angular/core';
import { HttpResponse, HttpEvent, HttpEventType } from '@angular/common/http';
import { Subscription } from 'rxjs';
import { finalize } from 'rxjs/operators';
import { NzMessageService, UploadFilter, UploadFile, UploadXHRArgs } from 'ng-zorro-antd';

import { SystemConfigService } from 'service/system-config.service';
import { SystemConfig } from 'src/app/model/system-config';
import { Enum } from 'src/app/model/enum';
import { FileService } from 'src/app/service/file.service';

@Component({
  selector: 'app-system-config',
  templateUrl: './system-config.component.html',
  styleUrls: ['./system-config.component.less']
})
export class SystemConfigComponent implements OnInit {
  updateWechatMenuLoading: boolean = false;
  // table
  dataList: SystemConfig[] = [];
  loading: boolean = true;
  sortKey: string;
  sortValue: string;

  // modal
  isVisible = false;
  isOkLoading = false;

  // form
  formData: SystemConfig = new SystemConfig();
  // 配置类型候选项
  typeOptionData: Enum[];
  // 当配置类型为枚举时,其值得候选值
  valueOptionData: Enum[];
  private localDate: Date;
  constructor(
    private message: NzMessageService,
    private fileService: FileService,
    private systemConfigService: SystemConfigService,
  ) { }

  // table
  sort(sort: { key: string, value: string }): void {
    if (!sort.key) { return; }
    this.sortKey = sort.key;
    this.sortValue = sort.value;
    this.dataList.sort((a, b) => {
      if (a[this.sortKey] == b[this.sortKey]) { return 0; }
      if (this.sortValue == 'ascend') {
        return a[this.sortKey] > b[this.sortKey] ? 1 : -1;
      } else if (this.sortValue == 'descend') {
        return a[this.sortKey] < b[this.sortKey] ? 1 : -1;
      }
      return 0;
    })
  }

  loadListData(): void {
    this.loading = true;
    this.systemConfigService.getConfigs()
      .subscribe((data: SystemConfig[]) => {
        this.loading = false;
        this.dataList = data;
        this.sort({ key: this.sortKey, value: this.sortValue });
      });
  }

  updateWechatMenu() {
    this.updateWechatMenuLoading = true
    this.systemConfigService.updateWechatMenu()
      .pipe(finalize(() => this.updateWechatMenuLoading = false))
      .subscribe(data => this.message.success('微信公众号菜单更新成功'));
  }

  // modal
  showModal(data: SystemConfig = new SystemConfig()): void {
    this.loadFormData(data);
    this.isVisible = true;
  }

  handleCancel(): void {
    this.isVisible = false;
  }

  handleOk(): void {
    this.isOkLoading = true;
    this.submitForm(this.formData)
      .pipe(finalize(() => this.isOkLoading = false))
      .subscribe(() => {
        this.isVisible = false;
        this.loadListData();
      });
  }

  // form
  loadFormData(data: SystemConfig): void {
    this.formData = { ...data };
    if (this.attributeValueComponentIsDate(data.attributeType)) {
      this.localDate = data.attributeValue ? new Date(+data.attributeValue) : new Date();
    }
    this.attributeTypeChange(data.attributeType);
  }

  private submitForm(data: SystemConfig) {
    if (this.attributeValueComponentIsDate(data.attributeType)) {
      data.attributeValue = this.localDate ? String(this.localDate.getTime()) : '';
    }
    return this.systemConfigService.update(data);
  }

  attributeTypeChange(attributeType: string): void {
    if (attributeType !== 'ENUM') { return }
    this.getOptionsByKey(this.formData.attributeKey)
  }

  private getOptionsByKey(attributeKey: string) {
    this.systemConfigService.getValueOptions(attributeKey)
      .subscribe(data => this.valueOptionData = data);
  }
  get uploadImgUrl() {
    let attributeValue: any = this.formData.attributeValue
    try { attributeValue = JSON.parse(attributeValue) } catch (e) { }
    return attributeValue && (attributeValue.url || attributeValue)
  }
  attributeValueComponentIsInput(attributeType: string): boolean {
    var type = {
      'STRING': 1
    }
    return type[attributeType];
  }
  attributeValueComponentIsSelect(attributeType: string): boolean {
    var type = {
      'ENUM': 1
    }
    return type[attributeType];
  }
  attributeValueComponentIsDate(attributeType: string): boolean {
    var type = {
      'DATE': 1
    }
    return type[attributeType];
  }
  attributeValueComponentIsUpload(attributeType: string): boolean {
    var type = {
      'WECHAT_MEDIA': 1
    }
    return type[attributeType];
  }

  // upload

  // 文件类型过滤器
  uploadFilters: UploadFilter[] = [
    {
      name: 'type',
      fn: (fileList: UploadFile[]) => {
        const filterFiles = fileList.filter(w => /image\/.*/i.test(w.type));
        if (filterFiles.length !== fileList.length) {
          this.message.error('文件格式不正确，只支持图片');
          return filterFiles;
        }
        return fileList;
      }
    }
  ];
  // 自定义文件上传请求
  uploadRequest = (item: UploadXHRArgs): Subscription => {
    // 始终返回一个 `Subscription` 对象，nz-upload 会在适当时机自动取消订阅
    return this.fileService.upload(item.action, item.file, this.formData)
      .subscribe((event: HttpEvent<any>) => {
        if (event.type === HttpEventType.UploadProgress) {
          if (event.total > 0) {
            (event as any).percent = event.loaded / event.total * 100;
          }
          // 处理上传进度条，必须指定 `percent` 属性来表示进度
          item.onProgress(event, item.file);
        } else if (event instanceof HttpResponse) {
          // 处理成功
          item.onSuccess(event.body, item.file, event);
        }
      }, (err) => {
        // 处理失败
        item.onError(err, item.file);
      });
  }
  uploadHandleChange(data: UploadFile): void {
    const status = data.file.status;
    if (status === 'done') {
      this.message.success(`${data.file.name} 文件上传成功`);
    } else if (status === 'error') {
      this.message.error(`${data.file.name} 文件上传失败`);
    }
  }

  ngOnInit(): void {
    this.loadListData();
    this.systemConfigService.getTypeOptions()
      .subscribe(data => this.typeOptionData = data);
  }
}
